// stores/user.ts
import { defineStore } from "pinia";
import { ElNotification } from "element-plus";
import * as Api from "@/api/index";
import { storage } from "@/utils/storage";
import type {
  LoginData,
  LoginSmsData,
  UserInfo,
  RegisterParams,
} from "@/api/types/user";

type PasswordLogin = {
  type: "password";
  username: string;
  password: string;
  captcha: string;
};

type SMSLogin = {
  type: "sms";
  phone: string;
  code: string;
};

type ScanLogin = {
  type: "scan";
  qrCode: string;
};

type LoginPayload = PasswordLogin | SMSLogin | ScanLogin;

const TOKEN_KEY = "accessToken";
const REFRESH_TOKEN_KEY = "refreshToken";

export const useUserStore = defineStore("user", {
  state: () => ({
    accessToken: storage.get(TOKEN_KEY) as string | null,
    refreshToken: storage.get(REFRESH_TOKEN_KEY) as string | null,
    tokenExpiresAt: null as number | null,
    userInfo: null as UserInfo | null,
    roles: [] as string[],
    permissions: [] as string[],
  }),
  getters: {
    isLoggedIn: (state) =>
    {
      return !!state.accessToken;
    },
    tokenExpired: (state) =>
      state.tokenExpiresAt !== null && state.tokenExpiresAt <= Date.now(),
    hasRefreshToken: (state) => !!state.refreshToken,
    userRoles: (state) => state.roles,
    userPermissions: (state) => state.permissions,
    userName: (state) => state.userInfo?.username || "",
    getUserInfo: (state) => {
      return state.userInfo as UserInfo;
    },
    avatar: (state) => state.userInfo?.avatar || "",
  },
  actions: {
    // 静默刷新token
    async silentRefresh() {
      try {
        console.log(this.refreshToken);
        const { token, refreshToken, expiresIn } = await Api.refreshToken(
          this.refreshToken
        );
        console.log("");
        this.accessToken = token;
        this.refreshToken = refreshToken;
        this.tokenExpiresAt = Date.now() + expiresIn * 1000;
        return true;
      } catch (error) {
        this.clearToken();
        throw error;
      }
    },
    goToLogin() {},
    async checkAuthStatus() {
      // 轻量级检查，不自动获取用户信息
      return !!this.accessToken && !isTokenExpired(this.accessToken);
    },
    async login(payload: LoginPayload) {
      switch (payload.type) {
        case "password":
          return this.passwordLogin(payload);
        case "sms":
          return this.smsLogin(payload);
        case "scan":
          return this.scanLogin(payload);
        default:
          throw new Error("Unsupported login type");
      }
    },

    async passwordLogin(payload: PasswordLogin) {
      const { username, password, captcha } = payload;
      try {
        const res = await Api.passwordLogin({ username, password, captcha });
        if (!res.token || !res.user?.id) {
          throw new Error("Invalid login response");
        }
        this.setToken(res.token, res.refreshToken);
        this.userInfo = res.user;
        return true;
      } catch (error) {
        this.handleError(error);
        this.clearToken();
        throw error;
      }
    },

    async smsLogin(payload: SMSLogin) {
      const { phone, code } = payload;
      const res = await Api.smsLogin({ phone, code });
      this.setToken(res.token, res.refreshToken);
      this.userInfo = res.user;
    },

    async scanLogin(payload: ScanLogin) {
      const { qrCode } = payload;
      const res = await Api.checkQRStatus({ qrCode });
      if (res.status === "confirmed") {
        this.setToken(res.token, res.refreshToken);
        this.userInfo = res.user;
      }
    },

    setToken(token: string, refreshToken: string) {
      this.accessToken = token;
      this.refreshToken = refreshToken;
      storage.set(TOKEN_KEY, token);
      storage.set(REFRESH_TOKEN_KEY, refreshToken);
      console.log("用户登录状态", this.isLoggedIn);

    },

    clearToken() {
      this.accessToken = null;
      this.refreshToken = null;
      this.tokenExpiresAt = null;
      this.userInfo = null;
      storage.remove(TOKEN_KEY);
      storage.remove(REFRESH_TOKEN_KEY);
    },
    // 定义存储服务的类型安全方法
    getToken(): string | null {
      const token = storage.get(TOKEN_KEY);
      return typeof token === "string" ? token : null;
    },

    getRefreshToken(): string | null {
      const refreshToken = storage.get(REFRESH_TOKEN_KEY);
      return typeof refreshToken === "string" ? refreshToken : null;
    },
    async initUserInfo() {
      const token = this.getToken();
      const refreshToken = this.getRefreshToken();

      if (!token || !refreshToken) {
        console.warn("Token 或 RefreshToken 不存在");
        return;
      }

      try {
        const data = await Api.getCurrUserInfo();
        console.log("初始化用户信息", data);

        // 类型断言确保数据符合 UserInfo 结构
        const userInfo: UserInfo = {
          id: data.id,
          username: data.username || "",
          nickname: data.nickname || "",
          avatar: data.avatar || "",
          email: data.email || "",
        };

        this.userInfo = userInfo;
        this.setToken(token, refreshToken);
      } catch (error) {
        console.error("初始化用户信息失败:", error);
        // 可以选择清除无效的token
        storage.remove(TOKEN_KEY);
        storage.remove(REFRESH_TOKEN_KEY);
      }
    },
    // 第二次请求：获取权限和角色（按需调用）
    async getUserPermissions() {
      try {
        const res = await Api.getUserPermissions();
      } catch (error) {
        console.log(error);
      }
    },
    async register(data: RegisterParams) {
      try {
        const res: any = await Api.register(data);
        const { token, refreshToken } = res;
        await this.setToken(token, refreshToken);
        return res;
      } catch (error: any) {
        this.handleError(error);
        return false;
      }
    },
    handleError(error: any) {
      console.error(error);
      // 处理错误，例如显示错误消息
      const errorMessage =
        error.response?.data?.message || "操作失败，请稍后重试";
      console.error("Error:", errorMessage);
      const status = error.response?.status;
      const code = error.response?.data?.code;
      console.error("Status:", status, "Code:", code);
      if (status === 400 && code === "INTERNAL_ERROR") {
        const errors = error.response?.data.data?.details;
        ElNotification({
          title: "Validation Error",
          message: errorMessage + ":" + errors,
          type: "error",
        });
      }
      if (status === 401 && code === "INTERNAL_ERROR") {
        ElNotification({
          title: "注册失败",
          message: errorMessage,
          type: "error",
        });
      }
    },
  },
  persist: {
    enabled: true,
    strategies: [
      {
        key: "user",
        storage: localStorage,
        paths: ["accessToken", "refreshToken", "userInfo"], // 明确指定需缓存的字段
      },
    ],
  },
});

// token过期检查函数
function isTokenExpired(token: string | null): boolean {
  if (!token) return true;

  try {
    // 尝试解析 token 负载
    const payload = JSON.parse(atob(token.split(".")[1]));
    // 检查过期时间 (exp) 是否存在
    if (typeof payload.exp !== "number") {
      // 如果没有过期时间，视为永不过期（不推荐生产环境这样做）
      return false;
    }
    return payload.exp * 1000 < Date.now();
  } catch {
    // 解析失败视为过期
    return true;
  }
}
